package com.szms.mobile.service;

import android.content.Context;

import com.szms.mobile.service.impl.BaseImpl;
import com.szms.mobile.util.ReflectionUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class Installer {

    private static Installer instance;

    private Context _context;

    private List<Class<? extends BaseImpl>> impls;

    private String servicePackage;

    private ConcurrentHashMap<Class, Object> ioc = new ConcurrentHashMap<>();

    private Installer(){
        servicePackage  = Installer.class.getPackage().getName();
    }

    private Installer(Context context){
        this();
        _context = context;
        impls = ReflectionUtils.getSubClassOf(context,servicePackage,BaseImpl.class);
    }

   public static Installer getInstance(Context context){
       if (instance==null){
           synchronized (Installer.class){
               if (instance==null){
                   instance = new Installer(context);
               }
           }
       }
       return instance;
   }



    public <T> T getService(Class<T> cls) {
        if (ioc.containsKey(cls)) {
            return (T) ioc.get(cls);
        }

        synchronized (cls) {
            for (Class<? extends BaseImpl> impl : impls) {
                if (cls.isAssignableFrom(impl)) {
                    // 创建实例
                    Constructor<? extends BaseImpl> constructor = null;
                    try {
                        constructor = impl.getConstructor(Context.class);
                    } catch (NoSuchMethodException e) {
                        throw new RuntimeException(e);
                    }

                    BaseImpl base = null;
                    try {
                        base = constructor.newInstance(_context);
                    } catch (IllegalAccessException | InstantiationException |
                             InvocationTargetException e) {
                        throw new RuntimeException(e);
                    }

                    if (!ioc.containsKey(cls)){
                        ioc.put(cls,base);
                    }
                    return (T) base;
                }
            }

        }
        throw new RuntimeException(String.format("找不到%s的实现类", cls));
    }


}
